package cn.tedu.boyou.member.service.impl;

import cn.tedu.boyou.cache.prefix.UserInfoKeyPrefix;
import cn.tedu.boyou.cache.prefix.VerifyCodeKeyPrefix;
import cn.tedu.boyou.cache.service.IRedisService;
import cn.tedu.boyou.cache.service.IUserInfoRedisService;
import cn.tedu.boyou.cache.service.IVerifyCodeRedisService;
import cn.tedu.boyou.common.exception.LogicException;
import cn.tedu.boyou.common.util.AssertUtil;
import cn.tedu.boyou.common.util.Consts;
import cn.tedu.boyou.member.domain.UserInfo;
import cn.tedu.boyou.member.mapper.UserInfoMapper;
import cn.tedu.boyou.member.service.IUserInfoService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.zhenzi.sms.ZhenziSmsClient;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StreamUtils;

import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class UserInfoServiceImpl implements IUserInfoService {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Value("${msg.url}")
    private String msgUrl;
    @Value("${msg.key}")
    private String msgKey;

    //不同服务间的引用要使用reference
    @Reference
    private IRedisService redisService;
    @Reference
    private IVerifyCodeRedisService verifyCodeRedisService;

    @Reference
    private IUserInfoRedisService userInfoRedisService;

    public UserInfo get(Long id) {
        return userInfoMapper.selectByPrimaryKey(id);
    }

    public boolean checkPhone(String phone) {

        return userInfoMapper.selectByPhone(phone) > 0;
    }
    
    
    //用户注册
    public void regist(String phone, String nickname, String password, String rpassword, String verifyCode) throws LogicException {
        AssertUtil.hasLength(phone,"手机号码不能为空.");
        AssertUtil.hasLength(nickname,"昵称不能为空.");
        AssertUtil.hasLength(password,"密码不能为空.");
        AssertUtil.hasLength(rpassword,"第二次输入的密码不能为空.");
        AssertUtil.hasLength(verifyCode,"验证码不能为空.");

        //2.判断2次输入的密码是否是一致
        AssertUtil.isEquals(password,rpassword,"两次输入的密码不一致");

        //3.判断手机是否唯一
        if(this.checkPhone(phone)){
            throw new LogicException("手机已被注册过了。");
        }
        //4.判断短信验证是否一致
        String resp = verifyCodeRedisService.getVerifyCode(VerifyCodeKeyPrefix.VERIFY_CODE,phone);

        //校验数据的一致性
        //验证码验证测试关闭
        System.out.println("获取到的验证码"+resp);
        System.out.println("用户输入的验证码"+verifyCode);
        //测试关闭 上线开启
        AssertUtil.isEquals(verifyCode, resp, "验证码验证错误");
        
        //5.注册   注册信息封装成对象
        UserInfo userInfo = new UserInfo();
        userInfo.setNickname(nickname);
        //给城市信息一个默认值
        userInfo.setCity("山的那边海的那边");
        userInfo.setPhone(phone);
        userInfo.setPassword(password);
        userInfo.setLevel(1);
        userInfo.setState(UserInfo.STATE_NORMAL);
        userInfo.setHeadImgUrl("/images/default.jpg");
        userInfoMapper.insert(userInfo);


    }
    
    
    //发送验证码
    public void sendVerifyCode(String phone) {
        //从redis中获取对应手机号的缓存的验证码信息
    	//String verifyCode = verifyCodeRedisService.getVerifyCode(,phone);
    	
        //假装已经进行手机号码校验啦
        if(this.checkPhone(phone)){
            throw new LogicException("手机已经注册过了");
        }
        
        
        //1.生成6为验证码
        String code = UUID.randomUUID().toString().substring(0,6);
        //2:发送到用户手机
        StringBuilder sb = new StringBuilder(80);
        sb.append("博游旅游网欢迎您!验证码为").append(code).append("请在").append(Consts.VERIFY_CODE_VAI_TIME).append("分钟之内注册，将有大礼包等你哦!");
        //假装已经发送
        System.out.println("验证码是"+sb);
        //发送短信
		ZhenziSmsClient client = new ZhenziSmsClient("https://sms_developer.zhenzikj.com","105195","062caa2c-c9ba-44f8-a89b-ba7895de2f06");
		Map<String, String> params = new HashMap<String, String>();
		params.put("message", sb.toString());
		params.put("number", phone);

        try {
			String resultTest=client.send(params);
			System.out.println(resultTest);
        } catch (Exception e) {
        	System.out.println("短信验证码出现异常");
            e.printStackTrace();
        }
        
//        if(vertifyCode!=null){
//        // if(verifyCode!=null){
//            return result.mark("验证码已经发送,请勿重复点击");
//        }
        
        
        //将手机号码和验证码缓存进redis
        verifyCodeRedisService.setVerifyCode(phone,code);
    }
    
    
    //用户登陆
    public String userLogin(String username, String password) throws LogicException{
        //判断账号或者密码
        UserInfo userInfo = userInfoMapper.selectUseByUsernameAndPassword(username, password);
        if(userInfo == null){
            throw new  LogicException("账号或密码错误");
        }

        return createToken(userInfo);
    }

    public List<UserInfo> list() {

        return userInfoMapper.selectAll();
    }

    public boolean update(UserInfo userInfo) {
        userInfoMapper.update(userInfo);
        return true;
    }

    private String createToken(UserInfo userInfo) {
        //缓存登录信息
        //缓存到redis；
        //key;  用户登录前缀 + token 一个随机的uuid
        //Value; userInfo
        String token = UUID.randomUUID().toString().replace("-", "");
        //添加到redis中
        userInfoRedisService.addToken(UserInfoKeyPrefix.USER_INFO_TOKEN,token,userInfo);
        return token;
    }


    private void sendMsg(String phone,String content)throws Exception{

        //方式1：HttpClient 这个开源框架， 完全可以模拟出浏览器所有操作

        //方式2：jdk自带的

        //指定访问地址
        URL url = new URL(msgUrl);
        //建立连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //设置请求方法
        connection.setRequestMethod("GET");
        //设置请求参数
        StringBuilder sb = new StringBuilder(100);
        sb.append("&mobile=").append(phone)
                .append("&content=").append("【创信】"+connection)
                .append("&appkey=").append(msgKey);
        //默认是false， 设置true表示输出参数
        connection.setDoOutput(true);
        connection.getOutputStream().write(sb.toString().getBytes("UTF-8"));
        //请求连接
        connection.connect();
        //获取响应数据
        String resp = StreamUtils.copyToString(connection.getInputStream(), Charset.forName("UTF-8"));
        System.out.println(resp);
    }

}
